from ctypes import c_ulong
from checkers_config import *

# Bits utilities
def bin32(num):
    short_string = bin(num)[2:]
    if 32 < len(short_string):
        raise ValueError('bin32 failed: number too big')
    elif 32 > len(short_string):
        bitstring = '%s%s' % ( (32 - len(short_string)) * '0', short_string, )
    else:
        bitstring = short_string
    return bitstring
        
def flipnum2(num):
    bitlen = num.bit_length()
    return ((num ^ g_precomputed_masks[bitlen]) | g_precomputed_aligned32[32 - bitlen])

def flipnum(num):
    return c_ulong(~num).value
    
def bit_count(unsigned_long):
    return (g_precomputed_16bits[unsigned_long & 0xFFFF] + g_precomputed_16bits[(unsigned_long >> 16) & 0xFFFF])
    
def get_set_indexes(unsigned_long):
    index_list = []
    append = index_list.append
    bitstring = (bin(unsigned_long)[2:])[::-1]
    for index, bitchar in enumerate(bitstring):
        if bitchar == '1':
            append(index)
    return index_list
        
class CheckersBoard(object):
    def __init__(self, board_to_copy=None):
        if board_to_copy is not None:
            self.cblacks = c_ulong(board_to_copy.cblacks.value)
            self.cwhites = c_ulong(board_to_copy.cwhites.value)
            self.ckings = c_ulong(board_to_copy.ckings.value)
        else:
            self.cblacks = c_ulong(0b11111111111100000000000000000000)
            self.cwhites = c_ulong(0b00000000000000000000111111111111)
            self.ckings = c_ulong(0)

    def set_bp(self, black_pieces):
        self.cblacks.value = black_pieces
    def set_wp(self, white_pieces):
        self.cwhites.value = white_pieces
    
    def copy_board_pieces(self, other_board):
        self.cblacks.value = other_board.cblacks.value
        self.cwhites.value = other_board.cwhites.value
        self.ckings.value = other_board.ckings.value
        self.ckings.value |= self.cwhites.value & 0xF0000000
        self.ckings.value |= self.cblacks.value & 0x0000000F
        
    def __str__(self):
        repr = '\n> White: %s, %d' % (get_set_indexes(self.cwhites.value), len(get_set_indexes(self.cwhites.value)))
        repr = '%s\n> Black: %s, %d' % (repr, get_set_indexes(self.cblacks.value), len(get_set_indexes(self.cblacks.value)))
        return repr
